enum StudentStage { elementary, middle, high }

class SensitiveFilter {
  SensitiveFilter._();

  // 默认使用更严格的小学策略
  static StudentStage stage = StudentStage.elementary;

  /// 通用敏感词（所有学段都拦截）
  static final Set<String> _baseKeywords = <String>{
    // 暴力相关
    '暴力',
    '打架',
    '殴打',
    '杀人',
    '杀害',
    '杀死',
    '自杀',
    '自残',
    '虐待',
    '虐童',
    '虐老',
    '虐宠',
    '血腥',
    '残忍',
    '恐吓',
    '威胁',
    '恐怖',
    '爆炸',
    '枪支',
    '枪械',
    '刀具',
    '匕首',
    '炸弹',
    '爆破',
    '火药',
    '枪杀',
    '枪击',
    // 色情低俗
    '色情',
    '黄色',
    '黄赌毒',
    '成人内容',
    '未成年人不宜',
    '裸照',
    '裸露',
    '性行为',
    '性暗示',
    '性骚扰',
    '性侵',
    '强奸',
    '猥亵',
    '淫秽',
    '裸聊',
    '约炮',
    '小黄片',
    '黄片',
    '胸部',
    '下体',
    '私处',
    '乳房',
    '阴茎',
    '阴道',
    '自慰',
    '手淫',
    // 赌博毒品
    '赌博',
    '赌钱',
    '赌注',
    '赌场',
    '赌徒',
    '赌局',
    '赌桌',
    '赌马',
    '赌球',
    '彩票诈骗',
    '毒品',
    '吸毒',
    '贩毒',
    '毒贩',
    '毒枭',
    '毒瘾',
    '毒资',
    '毒窝',
    '毒品交易',
    // 违法犯罪
    '违法',
    '犯罪',
    '诈骗',
    '敲诈',
    '勒索',
    '偷窃',
    '盗窃',
    '抢劫',
    '绑架',
    '走私',
    '贩卖',
    '假证',
    '假币',
    '假冒',
    '伪造',
    '侵权',
    '抄袭',
    '剽窃',
    '行贿',
    '受贿',
    '贪污',
    '腐败',
    '洗钱',
    '拐卖',
    '拐骗',
    // 侮辱歧视
    '谩骂',
    '侮辱',
    '歧视',
    '种族歧视',
    '地域歧视',
    '性别歧视',
    '骂人',
    '脏话',
    '傻逼',
    '傻子',
    '笨蛋',
    '蠢货',
    '死鬼',
    '死全家',
    '去死',
    '滚蛋',
    '废物',
    '垃圾',
    '狗东西',
    // 个人隐私
    '身份证号',
    '银行卡号',
    '手机号',
    '住址',
    '家庭住址',
    '个人信息',
    '隐私',
    '真实姓名',
    '身份证',
    '银行卡',
    '微信号',
    '支付宝账号',
    // 网络安全
    '黑客',
    '病毒',
    '木马',
    '攻击',
    '侵入',
    '窃取',
    '泄露',
    '钓鱼网站',
    '网络诈骗',
    '网络攻击',
    '网络暴力',
    '网暴',
    // 其他不适宜内容
    '邪教',
    '迷信',
    '宗教攻击',
    '极端主义',
    '分裂主义',
    '政治敏感',
    '敏感词',
    '敏感内容',
    '非法',
    '暴乱',
    '煽动',
    '反社会',
    '恐怖分子',
    '恐怖主义',
    '分裂国家',
    '辱华',
    '辱骂',
    '辱国',
    // 英文敏感词
    'sex',
    'porn',
    'nude',
    'naked',
    'kill',
    'suicide',
    'violence',
    'drugs',
    'drug',
    'gamble',
    'gambling',
    'hack',
    'hacker',
    'terror',
    'terrorist',
    'bomb',
    'gun',
    'abuse',
    'bully',
    'bitch',
    'fuck',
    'shit',
    'asshole',
    'bastard',
    'damn',
    'rape',
    'molest',
    'pedophile',
    'pedophilia',
    'incest',
    'orgy',
    'masturbate',
    'masturbation',
    'prostitute',
    'prostitution',
    'whore',
    'slut',
    'genital',
    'penis',
    'vagina',
    'breast',
    'nipple',
    'suck',
    'ejaculate',
    'cum',
    'fetish',
    'bdsm',
    'slave',
    'racist',
    'racism',
    'discriminate',
    'discrimination',
    'steal',
    'theft',
    'rob',
    'robbery',
    'fraud',
    'scam',
    'cheat',
    'cheater',
    'bribe',
    'corrupt',
    'corruption',
    // 可根据实际需求继续补充
  };

  /// 小学专有（更严格，增加一些表达与同义变体）
  static final Set<String> _elementaryExtra = <String>{
    '打人',
    '打我',
    '打他',
    '打她',
    '小黄片',
    '不适宜',
    '成人片',
    '成人网站',
    '裸',
    '露点',
    '开房',
    '约见',
    '约会不当',
    '骗钱',
    '骗小孩',
    '骂人话',
    '坏话',
  };

  /// 初中专有（中等严格）
  static final Set<String> _middleExtra = <String>{
    '群殴',
    '打群架',
    '血',
    '血迹',
    '刀片',
    '毒针',
    '网暴',
    '造谣',
    '散布隐私',
  };

  /// 高中专有（相对宽松但仍拦截核心）
  static final Set<String> _highExtra = <String>{
    '极端',
    '极端化',
    '过激',
    '重口',
    '软色情',
    '擦边',
    '约炮群',
    '开车',
  };

  static void addKeywords(Iterable<String> words, {StudentStage? forStage}) {
    final target = _targetSet(forStage);
    target.addAll(words.map((w) => w.trim()).where((w) => w.isNotEmpty));
  }

  static void removeKeywords(Iterable<String> words, {StudentStage? forStage}) {
    final target = _targetSet(forStage);
    for (final w in words) {
      target.remove(w.trim());
    }
  }

  static void clearKeywords() {
    _baseKeywords.clear();
    _elementaryExtra.clear();
    _middleExtra.clear();
    _highExtra.clear();
  }

  // 返回命中的第一个敏感词，未命中返回 null
  static String? findFirst(String input, {StudentStage? forStage}) {
    final String norm = _normalize(input);
    if (norm.isEmpty) return null;
    for (final word in _union(forStage ?? stage)) {
      if (word.isEmpty) continue;
      if (norm.contains(word)) return word;
    }
    return null;
  }

  static bool containsSensitive(String input, {StudentStage? forStage}) =>
      findFirst(input, forStage: forStage) != null;

  /// 外部根据文案配置学段
  static void setStageByGradeName(String? gradeName) {
    final g = (gradeName ?? '').toLowerCase();
    if (g.contains('小') || g.contains('primary') || g.contains('elementary')) {
      stage = StudentStage.elementary;
    } else if (g.contains('初') ||
        g.contains('junior') ||
        g.contains('middle')) {
      stage = StudentStage.middle;
    } else if (g.contains('高') || g.contains('senior') || g.contains('high')) {
      stage = StudentStage.high;
    }
  }

  static String _normalize(String text) {
    // 统一去除空白符与常见分隔符，便于简单包含匹配
    final String lowered = text.toLowerCase();
    final String removedSpaces = lowered.replaceAll(RegExp(r"\s+"), '');
    final String removedPunct = removedSpaces.replaceAll(
      RegExp(r"[\p{P}\p{S}]", unicode: true),
      '',
    );
    return removedPunct;
  }

  static Set<String> _union(StudentStage s) {
    // 合并基础 + 分级
    final set = <String>{..._baseKeywords};
    switch (s) {
      case StudentStage.elementary:
        set.addAll(_elementaryExtra);
        break;
      case StudentStage.middle:
        set.addAll(_middleExtra);
        break;
      case StudentStage.high:
        set.addAll(_highExtra);
        break;
    }
    return set;
  }

  static Set<String> _targetSet(StudentStage? s) {
    if (s == null) return _baseKeywords; // 默认操作基础词表
    switch (s) {
      case StudentStage.elementary:
        return _elementaryExtra;
      case StudentStage.middle:
        return _middleExtra;
      case StudentStage.high:
        return _highExtra;
    }
  }
}
